﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Commands;
using PloobsEngine.Draw;
using PloobsEngine.Features;
using PloobsEngine.Input;
using PloobsEngine.Light;
using PloobsEngine.Material;
using PloobsEngine.Modelo;
using PloobsEngine.Physics;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.SceneControl;

namespace Etapa1.Screens
{
    /// <summary>
    /// Picking Screen
    /// </summary>
    public class PickingScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;

        public PickingScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                                    
        }
        
        public override void LoadContent(EngineStuff es)
        {
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            ///Adicionando o Componente de Picking
            Picking pk = new Picking();
            engine.AddComponent(pk);

            base.LoadContent(es);

            #region Models
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(Vector3.Zero, sm);
                NormalDeferred shader = new NormalDeferred();
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj3 = new SimpleObject(mat, pi, sm);
                obj3.Name = "cenario";
                mundo.AddObject(obj3);
            }

            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    IModelo sm = new SimpleModel("..\\Content\\Model\\block", "..\\Content\\Textures\\blue");
                    sm.LoadModelo();
                    BoxObject pi = new BoxObject(new Vector3(i * 10, 100, j * 10), 1, 1, new Vector3(5));
                    pi.isMotionLess = true;
                    NormalDeferred shader = new NormalDeferred();
                    shader.Initialize();
                    IMaterial mat = new Material(shader);
                    IObject obj4 = new SimpleObject(mat, pi, sm);
                    obj4.Name = "Block " + i + " : " + j;
                    mundo.AddObject(obj4);
                }
            }



            {
                IModelo sm = new SimpleModel("..\\Content\\Model\\block", "..\\Content\\Textures\\blue");
                sm.LoadModelo();
                BoxObject pi = new BoxObject(new Vector3( 100, 50, 0 ), 1, 1, new Vector3(5));
                pi.isMotionLess = true;
                NormalDeferred shader = new NormalDeferred();
                shader.Initialize();
                IMaterial mat = new Material(shader);
                IObject obj4 = new SimpleObject(mat, pi, sm);
                obj4.Name = "SPECIAL " ;
                mundo.AddObject(obj4);

            }


            #endregion

            cam = new CameraFirstPerson(true);
            cam.FarPlane = 3000;

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.4f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);

            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;

            ///O PICKING FUNCIONA APENAS COM OBJETOS QUE TENHAM CORPO FISICO REAL !!!
            ///OS GHOST E OS DUMMY NUNCA SERAO SELECIONADOS
            ///Para ser informado a todo frame sobre as colisoes do raio, basta utilizar o outro construtor
            PickingParameters pp = new PickingParameters(cam, mundo, MouseButtons.RightButton);
            pp.Method = SegmentInterceptMethod.ALL;
            PickingRedirectorCallbackObserver prc = new PickingRedirectorCallbackObserver();
            prc.redirectPicking += new RedirectPicking(prc_redirectPicking);
            pp.Observers.Add(prc);
            CommandProcessor.getCommandProcessor().SendCommandSyncronous(pp);

            Drawing.setClearEveryFrame(false);
        }

        RayTestInfo ri = null;
        void prc_redirectPicking(object obj)
        {
            ri = obj as RayTestInfo;
            string objName = ri.Object.Name;
            Drawing.ClearAll();
            Drawing.Draw2dTextAt2dLocation("Selecionado -> " + objName, new Vector2(20, 20), Color.White);
            Drawing.Draw2dTextAt2dLocation("Position " + ri.ImpactPosition, new Vector2(20, 40), Color.White);
            Drawing.Draw2dTextAt2dLocation("Normal " + ri.ImpactNormal, new Vector2(20, 60), Color.White);
        }



    }
}

